/**
 * (写)创建连接文件
 * @param tar string|buffer 连接指向路径的值
 * 		指向可不存在, 若相对路径:相对src所在目录
 * @param src string|buffer 创建连接文件的路径
 * 		若以'/'结尾, 则在其目录下建tar同名文件
 * 		若存在软连接且指向同tar,则正常,否则异常
 * @param opt json|null 选项
 * 		hard: boolean 是否硬连接 默认false:软连接
 * 		syn: boolean 是否同步操作  默认false:异步
 * @return Promise|boolean  !opt.syn->Promise
 * 		boolean: true=成功, false=中断停止(!syn)
 * 		异步时: Promise追加.stop() -> 中断停止
 */
$.fsLnw = function(tar, src, opt=null){
	const NAME = require('node:path').basename;
	const $FS=require('node:fs'), ERR=(e,o)=>{
		if(o.X) return false;  let x=e.code!=='EEXIST';
		if(x || o.hard) return $.err('$.fsLnw', e);
		const a=!o.syn, tar=o.tar, src=o.src;
		x = v=>v===tar||(o.X?false:$.err('$.fsLnw',e));
		if(a) return $.fsAsync('readlink',src).then(x);
		try{ return x($FS.readlinkSync(src)); }
		catch(err){ return $.err('$.fsLnw',err); }
	};
	$.fsLnw = function(tar, src, opt=null){
		if(src.slice(-1)==='/') tar += NAME(tar);
		opt=$.mix({hard:false},opt,{tar,src,X:false});
		const k=opt.hard?'link':'symlink';  let w;
		if(opt.syn){
			try{ $FS[k+'Sync'](tar,src); return true; }
			catch(err){ return ERR(err,opt); }
		}
		w=$.fsAsync(k,tar,src).then(()=>true);
		w = w.catch(err=>ERR(err,opt));
		w.stop=()=>opt.X=true;  return w;
	};
	return $.fsLnw(tar, src, opt);
};
